#!/bin/bash

# 一键启动脚本 - Spring Cloud Alibaba 分布式事务演示项目
# 功能：检查环境、启动服务、运行测试

# 注意：不设置 set -e，允许脚本继续执行以显示所有检查结果

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

print_step() {
    echo ""
    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${BLUE}  $1${NC}"
    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
}

# 检查命令是否存在
check_command() {
    if command -v $1 &> /dev/null; then
        print_success "$1 已安装"
        return 0
    else
        print_warning "$1 未安装"
        return 1
    fi
}

# 安装依赖（使用 brew）
install_dependency() {
    local package=$1
    local install_cmd=$2

    print_info "正在安装 $package..."

    # 执行安装命令
    eval $install_cmd

    if [ $? -eq 0 ]; then
        print_success "$package 安装成功"
        return 0
    else
        print_error "$package 安装失败"
        return 1
    fi
}

# 并行等待多个服务就绪
wait_for_services_parallel() {
    local services=("$@")
    local max_wait=45
    local wait_time=0

    print_info "并行等待服务启动..."

    while [ $wait_time -lt $max_wait ]; do
        local all_ready=true

        for service_info in "${services[@]}"; do
            IFS='|' read -r service_name url <<< "$service_info"
            if ! curl -s --connect-timeout 2 "$url" &> /dev/null; then
                all_ready=false
                break
            fi
        done

        if [ "$all_ready" = true ]; then
            print_success "所有服务启动成功（耗时 ${wait_time}秒）"
            return 0
        fi

        sleep 1
        wait_time=$((wait_time + 1))
        echo -n "."
    done

    echo ""
    print_warning "服务启动超时（${max_wait}秒）"
    return 1
}

# 等待 MySQL 就绪
wait_for_mysql() {
    local max_wait=$1
    local wait_time=0

    print_info "等待 MySQL 启动..."

    while [ $wait_time -lt $max_wait ]; do
        if docker exec springcloud-mysql mysql -uroot -proot123456 -e "SELECT 1;" &> /dev/null; then
            print_success "MySQL 启动成功（耗时 ${wait_time}秒）"
            return 0
        fi
        sleep 1
        wait_time=$((wait_time + 1))
        echo -n "."
    done

    echo ""
    print_warning "MySQL 启动超时（${max_wait}秒）"
    return 1
}

# 等待 Redis 就绪
wait_for_redis() {
    local max_wait=$1
    local wait_time=0

    print_info "等待 Redis 启动..."

    while [ $wait_time -lt $max_wait ]; do
        if docker exec springcloud-redis redis-cli ping &> /dev/null; then
            print_success "Redis 启动成功（耗时 ${wait_time}秒）"
            return 0
        fi
        sleep 1
        wait_time=$((wait_time + 1))
        echo -n "."
    done

    echo ""
    print_warning "Redis 启动超时（${max_wait}秒）"
    return 1
}

# 步骤 1：检查前置条件
step1_check_prerequisites() {
    print_step "步骤 1：检查前置条件"

    # 检查 JDK
    if check_command java; then
        java_version=$(java -version 2>&1 | head -n 1)
        print_info "Java 版本: $java_version"
    else
        print_error "JDK 未安装，正在自动安装..."
        install_dependency "JDK" "brew install openjdk@11"
    fi

    # 检查 Maven
    if check_command mvn; then
        mvn_version=$(mvn -version | head -n 1)
        print_info "Maven 版本: $mvn_version"
    else
        print_error "Maven 未安装，正在自动安装..."
        install_dependency "Maven" "brew install maven"
    fi

    # 检查 Docker
    if check_command docker; then
        docker_version=$(docker --version)
        print_info "Docker 版本: $docker_version"
    else
        print_error "Docker 未安装，正在自动安装..."
        install_dependency "Docker" "brew install --cask docker"
    fi

    # 检查 Docker Compose
    if check_command docker-compose; then
        docker_compose_version=$(docker-compose --version)
        print_info "Docker Compose 版本: $docker_compose_version"
    else
        print_error "Docker Compose 未安装，正在自动安装..."
        install_dependency "Docker Compose" "brew install docker-compose"
    fi

    print_success "前置条件检查完成"
}

# 步骤 2：检查 Docker 是否运行
step2_check_docker() {
    print_step "步骤 2：检查 Docker 是否运行"

    if docker ps &> /dev/null; then
        print_success "Docker 正在运行"
    else
        print_error "Docker 未运行，请先启动 Docker"
        print_info "macOS: 打开 Docker Desktop"
        print_info "Linux: sudo systemctl start docker"
        exit 1
    fi
}

# 步骤 3：启动基础设施
step3_start_infrastructure() {
    print_step "步骤 3：启动基础设施（Nacos、Seata、MySQL、Redis）"

    # 检查是否已经启动
    if docker-compose ps 2>/dev/null | grep -q "Up"; then
        print_warning "基础设施已经在运行"
        docker-compose ps
    else
        print_info "启动基础设施..."
        if [ -f "./scripts/start.sh" ]; then
            bash ./scripts/start.sh
        else
            print_error "启动脚本不存在: ./scripts/start.sh"
            exit 1
        fi

        # 动态检测服务就绪（减少等待时间）
        wait_for_mysql 20
        wait_for_redis 15
        wait_for_service "Nacos" "http://localhost:8848/nacos/v1/console/health/readiness" 45
    fi
}

# 步骤 4：初始化数据库
step4_init_database() {
    print_step "步骤 4：初始化数据库"

    cd projects/spring-cloud-demo

    if [ -f "resources/scripts/01-初始化数据库.sh" ]; then
        print_info "执行数据库初始化脚本..."
        bash resources/scripts/01-初始化数据库.sh

        # 验证数据库初始化
        print_info "验证数据库初始化..."
        order_count=$(docker exec springcloud-mysql mysql -uroot -proot123456 seata_order \
            -e "SELECT COUNT(*) as count FROM tb_order;" 2>/dev/null | tail -n +2)

        if [ "$order_count" -gt 0 ]; then
            print_success "数据库初始化成功，订单数量: $order_count"
        else
            print_warning "数据库可能未初始化或为空"
        fi
    else
        print_error "数据库初始化脚本不存在"
        exit 1
    fi

    cd ../..
}

# 步骤 5：启动微服务
step5_start_services() {
    print_step "步骤 5：启动微服务（Order、Storage、Account）"

    cd projects/spring-cloud-demo

    if [ -f "resources/scripts/02-启动所有服务.sh" ]; then
        print_info "启动所有微服务..."
        bash resources/scripts/02-启动所有服务.sh

        # 并行检测服务就绪
        local services=(
            "Order Service|http://localhost:8001/order/health"
            "Storage Service|http://localhost:8002/storage/health"
            "Account Service|http://localhost:8003/account/health"
        )
        wait_for_services_parallel "${services[@]}"
    else
        print_error "启动脚本不存在"
        exit 1
    fi

    cd ../..
}

# 步骤 6：运行测试
step6_run_tests() {
    print_step "步骤 6：运行测试"

    cd projects/spring-cloud-demo

    # 询问是否运行测试
    read -p "是否运行测试？(y/n): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_info "跳过测试"
        cd ../..
        return
    fi

    # 运行 Seata 功能测试
    if [ -f "resources/scripts/04-Seata功能测试.sh" ]; then
        print_info "运行 Seata 功能测试..."
        bash resources/scripts/04-Seata功能测试.sh
    fi

    # 运行回滚测试
    if [ -f "resources/scripts/05-Seata回滚测试.sh" ]; then
        print_info "运行 Seata 回滚测试..."
        bash resources/scripts/05-Seata回滚测试.sh
    fi

    # 运行 Sentinel 限流测试
    if [ -f "resources/scripts/06-Sentinel限流测试.sh" ]; then
        print_info "运行 Sentinel 限流测试..."
        bash resources/scripts/06-Sentinel限流测试.sh
    fi

    cd ../..
}

# 主函数
main() {
    echo ""
    echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║                                                           ║${NC}"
    echo -e "${GREEN}║   Spring Cloud Alibaba 一键启动脚本                    ║${NC}"
    echo -e "${GREEN}║                                                           ║${NC}"
    echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
    echo ""

    # 检查是否在项目根目录
    if [ ! -f "docker-compose.yaml" ]; then
        print_error "请在项目根目录执行此脚本"
        exit 1
    fi

    # 执行各个步骤
    step1_check_prerequisites
    step2_check_docker
    step3_start_infrastructure
    step4_init_database
    step5_start_services
    step6_run_tests

    # 完成
    print_step "🎉 启动完成！"

    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "  🌐 访问控制台"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    echo "  Nacos:    http://localhost:8848/nacos"
    echo "  Sentinel: http://localhost:8858"
    echo "  Seata:    http://localhost:7091"
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "  📝 常用命令"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    echo "  查看服务状态: ./scripts/status.sh"
    echo "  查看日志:     ./scripts/logs.sh"
    echo "  停止服务:     ./scripts/stop.sh"
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
}

# 执行主函数
main

